package java_thinking.unit_20._20_1;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @Desc:   20.2.3 注解处理器案例，它将读取一个类文件，检查其上的数据库注解，并生成用来创建数据库的sql命令
 * @author: cww
 * @DateTime: 2019-05-26 21:48
 */

public class TableCreator {
    public static void main(String[] args) throws ClassNotFoundException {
        String[] classNames = new String[]{"Member.class"};
        for (String className : classNames) {
            Class<?> cl = Class.forName(className);
            DBTable dbTable = cl.getAnnotation(DBTable.class);
            if (dbTable == null) {
                System.out.println("No DBTable annotations in class " + className);
                continue;
            }
            String tableName = dbTable.name();
            if (tableName.length() < 1) {
                tableName = cl.getName().toLowerCase();
            }
            List<String> columnDefs = new ArrayList<String>();
            //遍历所有filed
            for (Field field : cl.getDeclaredFields()) {
                String columnName = null;
                //获取field的所有注解
                Annotation[] anns = field.getDeclaredAnnotations();
                if (anns.length < 1) {
                    //没有任何注解的配置
                    continue;
                }
                //依次判断当前注解的类型
                if (anns[0] instanceof SQLInteger) {
                    SQLInteger sInt = (SQLInteger) anns[0];
                    //使用域的名字，如果SQLInteger没有定义
                    if (sInt.name().length() < 1) {
                        columnName = field.getName().toUpperCase();
                    } else {
                        columnName = sInt.name();
                    }
                    //添加字段的sql放入list中
                    columnDefs.add(columnName + " INT" + getConstraints(sInt.constraints()));
                } else if (anns[0] instanceof SQLString) {
                    SQLString sString = (SQLString) anns[0];
                    if(sString.name().length() < 1)
                        columnName = field.getName().toUpperCase();
                    else
                        columnName = sString.name();
                    columnDefs.add(columnName + " VARCHAR(" + sString.value() + ")" +
                            getConstraints(sString.constraints()));
                }
                //拼装sql语句
                StringBuilder createCommand = new StringBuilder("CREATE TABLE " + tableName + "(");
                for(String columnDef : columnDefs) {
                    createCommand.append("\n    " + columnDef + ",");
                }
                String tableCreate = createCommand.substring(0, createCommand.length() - 1) + ");";
                System.out.println("Table Creation SQL for " + className + " is :\n" + tableCreate);
            }
        }
    }

    private static String getConstraints(Constraints con) {
        String constraints = "";
        if (!con.allowNull()) {
            constraints += " NOT NULL";
        }
        if (con.primaryKey()) {
            constraints += " PRIMARY KEY";
        }
        if(con.unique())
            constraints += " UNIQUE";
        return constraints;
    }
}
/* Output:
Table Creation SQL for annotations.Member is :
CREATE TABLE MEMBER(
    FIRSTNAME VARCHAR(30));
Table Creation SQL for annotations.Member is :
CREATE TABLE MEMBER(
    FIRSTNAME VARCHAR(30),
    LASTNAME VARCHAR(50));
Table Creation SQL for annotations.Member is :
CREATE TABLE MEMBER(
    FIRSTNAME VARCHAR(30),
    LASTNAME VARCHAR(50),
    AGE INT);
Table Creation SQL for annotations.Member is :
CREATE TABLE MEMBER(
    FIRSTNAME VARCHAR(30),
    LASTNAME VARCHAR(50),
    AGE INT,
    HANDLE CHARACTER(15) PRIMARY KEY);
Table Creation SQL for annotations.Member is :
CREATE TABLE MEMBER(
    FIRSTNAME VARCHAR(30),
    LASTNAME VARCHAR(50),
    AGE INT,
    HANDLE CHARACTER(15) PRIMARY KEY,
    ISVIP BOOLEAN);
*///:~